package com.jilefojing.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.jilefojing.beans.data.enums.ResponseEnum;
import com.jilefojing.beans.data.manager.response.RTagSourceData;
import com.jilefojing.beans.data.manager.response.RecommendData;
import com.jilefojing.beans.data.manager.response.TagData;
import com.jilefojing.beans.data.response.base.ResponseData;
import com.jilefojing.beans.enums.ItemTypeEnumForSource;
import com.jilefojing.beans.enums.StatusEnumForPublish;
import com.jilefojing.beans.exception.UserContextException;
import com.jilefojing.beans.pojos.RCategorySource;
import com.jilefojing.beans.pojos.RTagSource;
import com.jilefojing.beans.pojos.Tag;
import com.jilefojing.beans.pojos.enhanced.EnhancedEAudio;
import com.jilefojing.beans.pojos.enhanced.EnhancedEVideo;
import com.jilefojing.beans.pojos.enhanced.EnhancedRTagSource;
import com.jilefojing.beans.pojos.enhanced.EnhancedTag;
import com.jilefojing.beans.pojos.enhanced.base.BaseEnhanced;
import com.jilefojing.beans.query.EAudioQuery;
import com.jilefojing.beans.query.EVideoQuery;
import com.jilefojing.beans.query.RTagSourceQuery;
import com.jilefojing.beans.query.TagQuery;
import com.jilefojing.beans.vo.Order;
import com.jilefojing.beans.vo.Pagination;
import com.jilefojing.context.beans.vo.UserContext;
import com.jilefojing.controller.base.BaseController;
import com.jilefojing.controller.convent.CommonConvent;
import com.jilefojing.service.IEAudioService;
import com.jilefojing.service.IEVideoService;
import com.jilefojing.service.IRTagSourceService;
import com.jilefojing.service.ISourceService;
import com.jilefojing.service.ITagService;
import com.jilefojing.util.Detect;

@Controller
@RequestMapping("tag")
public class TagController extends BaseController {
	@Autowired
	private ISourceService sourceService;
	@Autowired
	private ITagService tagService;
	@Autowired
	private IRTagSourceService rTagSourceService;
	@Autowired
	private IEVideoService eVideoService;
	@Autowired
	private IEAudioService eAudioService;

	@RequestMapping("relation-config.html")
	public String torRelationConfig(long id, HttpServletRequest request) {
		return "tag/relation_config";
	}

	@RequestMapping(value = "update", method = RequestMethod.POST)
	public @ResponseBody ResponseData update(Tag tag, HttpServletRequest request) {
		ResponseData responseData = new ResponseData();
		try {
			UserContext userContext = super.getUserContext();
			tagService.update(tag, userContext);
		} catch (UserContextException e) {
			if (e.getResponse() != null) {
				responseData.setResponseEnum(e.getResponse());
			} else {
				responseData.setResponseEnum(ResponseEnum.UNKNOWN);
				responseData.setResponseMessage(e.getMessage());
			}
		}
		return responseData;
	}

	@RequestMapping(value = "add", method = RequestMethod.POST)
	public @ResponseBody ResponseData add(Tag tag, HttpServletRequest request) {
		ResponseData responseData = new ResponseData();
		try {
			UserContext userContext = super.getUserContext();
			tagService.add(tag, userContext);
		} catch (UserContextException e) {
			if (e.getResponse() != null) {
				responseData.setResponseEnum(e.getResponse());
			} else {
				responseData.setResponseEnum(ResponseEnum.UNKNOWN);
				responseData.setResponseMessage(e.getMessage());
			}
		}
		return responseData;
	}

	@RequestMapping("add.html")
	public String toAddPage() {
		return "tag/add";
	}

	@RequestMapping("delete")
	public @ResponseBody ResponseData delete(@RequestParam("ids[]") ArrayList<Long> ids, boolean force, HttpServletRequest request) {

		ResponseData responseData = new ResponseData();
		try {
			UserContext userContext = super.getUserContext();
			tagService.deleteByIds(ids, force, userContext);
		} catch (UserContextException e) {
			if (e.getResponse() != null) {
				responseData.setResponseEnum(e.getResponse());
			} else {
				responseData.setResponseEnum(ResponseEnum.UNKNOWN);
				responseData.setResponseMessage(e.getMessage());
			}
		}
		return responseData;
	}

	@RequestMapping("item/add.html")
	public String toAddItemPage(short itemType, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();
		ItemTypeEnumForSource itemTypeEnumForSource = ItemTypeEnumForSource.getItemTypeEnumByCode(itemType);

		return "tag/" + itemTypeEnumForSource.getItemClass().getSimpleName().toLowerCase() + "_add";
	}

	@RequestMapping("item/delete")
	public @ResponseBody ResponseData deleteItem(long id, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();

		ResponseData responseData = new ResponseData();
		rTagSourceService.deleteById(id, userContext);

		return responseData;
	}

	@RequestMapping(value = "item/update", method = RequestMethod.POST)
	public @ResponseBody ResponseData updateItem(RTagSource rTagSource, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();

		ResponseData responseData = new ResponseData();
		try {
			rTagSourceService.update(rTagSource, userContext);
		} catch (UserContextException e) {
			if (e.getResponse() != null) {
				responseData.setResponseEnum(e.getResponse());
			} else {
				responseData.setResponseEnum(ResponseEnum.UNKNOWN);
				responseData.setResponseMessage(e.getMessage());
			}
		}

		return responseData;
	}

	@RequestMapping("item/list")
	public @ResponseBody Map<String, Object> getListItems(Short itemType, Long itemId, Long tagId, Short status, String like_title, String like_tag_name, HttpServletRequest request)
			throws UserContextException {
		UserContext userContext = super.getUserContext();

		int page = Integer.valueOf(request.getParameter("page"));
		int rows = Integer.valueOf(request.getParameter("rows"));

		String sortsStr = request.getParameter("sort");
		String ordersStr = request.getParameter("order");

		Pagination<EnhancedRTagSource> pagination = new Pagination<EnhancedRTagSource>(page, rows, true);
		if (!Detect.notEmpty(sortsStr)) {
			pagination.addOrder(new Order(RCategorySource.COLUMN_SORT, Order.ORDER_DESC)).addOrder(new Order(RCategorySource.COLUMN_UPDATE_TIME, Order.ORDER_DESC));
		} else {
			super.addSorts(sortsStr, ordersStr, "tag", RTagSource.COLUMN_TAG_ID, pagination);
			super.addSorts(sortsStr, ordersStr, RTagSource.FIELD_SORT, RTagSource.COLUMN_SORT, pagination);
			super.addSorts(sortsStr, ordersStr, RTagSource.FIELD_UPDATETIME, RTagSource.COLUMN_UPDATE_TIME, pagination);
		}

		RTagSourceQuery rTagSourceQuery = new RTagSourceQuery();
		if (itemType != null && itemType > 0) {
			ItemTypeEnumForSource itemTypeEnumForSource = ItemTypeEnumForSource.getItemTypeEnumByCode(itemType);
			rTagSourceQuery.setItemTypes(Arrays.asList(new ItemTypeEnumForSource[] { itemTypeEnumForSource }));
			if (Detect.notEmpty(like_title)) {
				List<Long> itemIds = this.getItemIdsByLikeTitle(itemTypeEnumForSource, like_title, userContext);
				if (!Detect.notEmpty(itemIds)) {
					Map<String, Object> resultMap = new HashMap<String, Object>();
					resultMap.put("total", 0);
					resultMap.put("rows", new ArrayList<RecommendData>());
					return resultMap;
				}
				rTagSourceQuery.setItemIds(itemIds);
			}
		}
		if (itemId != null && itemId > 0) {
			rTagSourceQuery.setItemIds(Arrays.asList(new Long[] { itemId }));
		}
		if (status != null && status > 0) {
			rTagSourceQuery.setStatuses(Arrays.asList(new StatusEnumForPublish[] { StatusEnumForPublish.getStatusEnumByCode(status) }));
		}
		List<Long> tagIds = new ArrayList<Long>();
		if (tagId != null && tagId > 0) {
			tagIds.add(tagId);
		}
		if (Detect.notEmpty(like_tag_name)) {
			TagQuery tagQuery = new TagQuery();
			tagQuery.setLike_name(like_tag_name);
			List<EnhancedTag> enhancedTags = tagService.getPagination(tagQuery, new Pagination<EnhancedTag>(1, Integer.MAX_VALUE), userContext).getItems();
			if (!Detect.notEmpty(enhancedTags)) {
				Map<String, Object> resultMap = new HashMap<String, Object>();
				resultMap.put("total", 0);
				resultMap.put("rows", new ArrayList<RTagSourceData>());
				return resultMap;
			}
			for (EnhancedTag _EnhancedTag : enhancedTags) {
				tagIds.add(_EnhancedTag.getId());
			}
		}

		if (Detect.notEmpty(tagIds)) {
			rTagSourceQuery.setTagIds(tagIds);
		}

		pagination = rTagSourceService.getPagination(rTagSourceQuery, pagination, userContext);

		List<RTagSourceData> rTagSourceDatas = new ArrayList<RTagSourceData>();
		Map<String, Object> resultMap = new HashMap<String, Object>();

		resultMap.put("total", pagination.getCount());
		if (Detect.notEmpty(pagination.getItems())) {
			List<BaseEnhanced> enhancedItems = new ArrayList<BaseEnhanced>();
			for (EnhancedRTagSource _EnhancedRTagSource : pagination.getItems()) {
				enhancedItems.add(_EnhancedRTagSource.getEnhancedItem());
			}
			enhancedItems = sourceService.appendEnhancedParent2EnhancedItems(enhancedItems, userContext);

			rTagSourceDatas = CommonConvent.convent2RTagSourceDatas(pagination.getItems());
		}
		resultMap.put("rows", rTagSourceDatas);

		return resultMap;
	}

	private List<Long> getItemIdsByLikeTitle(ItemTypeEnumForSource itemType, String like_title, UserContext userContext) {
		List<Long> itemIds = new ArrayList<Long>();
		@SuppressWarnings("rawtypes")
		Pagination pagination = null;
		if (itemType == ItemTypeEnumForSource.VIDEO) {
			EVideoQuery eVideoQuery = new EVideoQuery();
			eVideoQuery.setLike_title(like_title);
			pagination = eVideoService.getPagination(eVideoQuery, new Pagination<EnhancedEVideo>(1, Integer.MAX_VALUE, false), userContext);
		} else if (itemType == ItemTypeEnumForSource.AUDIO) {
			EAudioQuery eAudioQuery = new EAudioQuery();
			eAudioQuery.setLike_title(like_title);
			pagination = eAudioService.getPagination(eAudioQuery, new Pagination<EnhancedEAudio>(1, Integer.MAX_VALUE, false), userContext);
		} else {
			throw new IllegalArgumentException("[暂不支持此类型的标题查询]");
		}
		if (Detect.notEmpty(pagination.getItems())) {
			@SuppressWarnings("unchecked")
			List<BaseEnhanced> enhancedItems = (List<BaseEnhanced>) pagination.getItems();
			for (BaseEnhanced _BaseEnhanced : enhancedItems) {
				itemIds.add(_BaseEnhanced.getDynamicId());
			}
		}
		return itemIds;
	}

	@RequestMapping("item/list.html")
	public String toItemListPage(short itemType, HttpServletRequest request) {
		ItemTypeEnumForSource itemTypeEnumForSource = ItemTypeEnumForSource.getItemTypeEnumByCode(itemType);
		return "tag/" + itemTypeEnumForSource.getItemClass().getSimpleName().toLowerCase() + "_list";
	}

	@RequestMapping("list.html")
	public String toListPage(HttpServletRequest request) {
		return "tag/list";
	}

	/**
	 * 获取标签列表
	 * 
	 * @param request
	 * @return
	 * @throws UserContextException
	 */
	@RequestMapping("list2")
	public @ResponseBody Map<String, Object> getList2(String like_name, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();

		int page = Integer.valueOf(request.getParameter("page"));
		int rows = Integer.valueOf(request.getParameter("rows"));

		String sortsStr = request.getParameter("sort");
		String ordersStr = request.getParameter("order");

		Pagination<EnhancedTag> pagination = new Pagination<EnhancedTag>(page, rows, true);
		if (!Detect.notEmpty(sortsStr)) {
			pagination.addOrder(new Order(Tag.COLUMN_CREATE_TIME, Order.ORDER_DESC));
		} else {
			super.addSorts(sortsStr, ordersStr, Tag.FIELD_CREATETIME, Tag.COLUMN_CREATE_TIME, pagination);
		}

		TagQuery tagQuery = new TagQuery();
		if (Detect.notEmpty(like_name)) {
			tagQuery.setLike_name(like_name);
		}

		pagination = tagService.getPagination(tagQuery, pagination, userContext);

		Map<String, Object> resultMap = new HashMap<String, Object>();
		resultMap.put("total", pagination.getCount());
		List<TagData> tagDatas = new ArrayList<TagData>();
		if (Detect.notEmpty(pagination.getItems())) {
			pagination.setItems(tagService.appendCountSourcesByItemTypes(pagination.getItems(), null, userContext));
			tagDatas = CommonConvent.convent2TagDatas(pagination.getItems());
		}
		resultMap.put("rows", tagDatas);
		return resultMap;
	}

	/**
	 * 获取标签列表
	 * 
	 * @param request
	 * @return
	 * @throws UserContextException
	 */
	@RequestMapping("list")
	public @ResponseBody List<TagData> getList(Short itemType, Long itemId, String like_name, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();

		Pagination<EnhancedTag> pagination = new Pagination<EnhancedTag>(1, Integer.MAX_VALUE, false);
		TagQuery tagQuery = new TagQuery();
		tagQuery.setLike_name(like_name);
		pagination = tagService.getPagination(tagQuery, pagination, userContext);

		List<TagData> tagDatas = new ArrayList<TagData>();
		if (Detect.notEmpty(pagination.getItems())) {
			tagDatas = CommonConvent.convent2TagDatas(pagination.getItems());

			if (itemType != null && itemId != null && itemType > 0 && itemId > 0) {
				BaseEnhanced enhancedItem = sourceService.getEnhancedItem(ItemTypeEnumForSource.getItemTypeEnumByCode(itemType), itemId, userContext);
				enhancedItem = sourceService.appendEnhancedTags2EnhancedItem(enhancedItem, userContext);
				List<EnhancedTag> enhancedTags = (List<EnhancedTag>) enhancedItem.get("getEnhancedTags");
				this.appendChecked(enhancedTags, tagDatas);
			}
		}
		return tagDatas;
	}

	private void appendChecked(List<EnhancedTag> enhancedTags, List<TagData> tagDatas) {
		if (Detect.notEmpty(enhancedTags) && Detect.notEmpty(tagDatas)) {
			for (TagData _child : tagDatas) {
				for (EnhancedTag _EnhancedTag : enhancedTags) {
					if (_child.getId() == _EnhancedTag.getId()) {
						_child.setChecked(true);
						break;
					}
				}
			}
		}
	}

	/**
	 * 类别设置
	 * 
	 * @param itemType
	 * @param itemId
	 * @param request
	 * @return
	 * @throws UserContextException
	 */
	@RequestMapping("set")
	public @ResponseBody ResponseData set(short itemType, long itemId, @RequestParam("tagIds[]") ArrayList<Long> tagIds, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();
		ResponseData responseData = new ResponseData();

		sourceService.addTags(ItemTypeEnumForSource.getItemTypeEnumByCode(itemType), itemId, tagIds, userContext);

		return responseData;
	}

	/**
	 * 标签设置界面
	 * 
	 * @param itemType
	 * @param itemId
	 * @param request
	 * @return
	 * @throws UserContextException
	 */
	@RequestMapping("set.html")
	public String setPage(short itemType, long itemId, HttpServletRequest request) throws UserContextException {
		UserContext userContext = super.getUserContext();

		BaseEnhanced baseEnhanced = sourceService.getEnhancedItem(ItemTypeEnumForSource.getItemTypeEnumByCode(itemType), itemId, userContext);

		request.setAttribute("itemType", ItemTypeEnumForSource.getItemTypeEnumByCode(itemType));
		request.setAttribute("entity", baseEnhanced);

		return "tag/set";
	}
}
